package com.jqb.webservice.client;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.jqb.webservice.service.impl.MixService;
import com.jqb.webservice.vo.User;


public class WebServiceClient01 {
	//服务网址
	private String webUrl = "http://localhost:9999/service?wsdl";
	//服务命名空间[所有QName必须加上此命名空间]
	private String serviceNs = "http://impl.service.webservice.jqb.com/";
	//服务名称
	private String serviceName = "MixServiceImplService";
	@Test
	public void test01(){
		try {
			URL url = new URL(webUrl);
			QName qname = new QName(serviceNs,serviceName) ;
			Service service = Service.create(url, qname);
			MixService mixSevice = service.getPort(MixService.class);
			System.out.println(mixSevice.add(1, 2));
			System.out.println(mixSevice.addUser(new User(1001,"dong","dong123")));
			System.out.println(mixSevice.getUsers());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	@Test
	public void test02(){
		try {
			//通过消息工厂创建消息
			SOAPMessage soapMsg =  MessageFactory.newInstance().createMessage();
			//获取SOAPPart
			SOAPPart soapPart = soapMsg.getSOAPPart();
			//获取SOAPEnvelope
			SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
			//获取SOAPBody
			SOAPBody soapBody = soapEnvelope.getBody();
			//创建QName
			/*<sx:add xmlns="http://service.webservice.jqb.com"><a>1</a><b>2</b></sx:add>*/
			QName qname = new QName(serviceNs, "add", "sx");
			SOAPBodyElement  element = soapBody.addBodyElement(qname);
			element.addChildElement("a").setValue("1");
			element.addChildElement("b").setValue("2");
			//打印消息
			soapMsg.writeTo(System.out);
			
		} catch (SOAPException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Test
	public void test03(){
		try {
			//创建服务
			URL url = new URL(webUrl);
			QName qname = new QName(serviceNs, serviceName);
			Service service = Service.create(url, qname);
			//创建Dispatch(消息方式)
			Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(serviceNs,"MixServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
			//创建SOAPMessage
			SOAPMessage soapMsg = MessageFactory.newInstance().createMessage();
			SOAPEnvelope soapEnvelope = soapMsg.getSOAPPart().getEnvelope();
			SOAPBody soapBody = soapEnvelope.getBody();
			//创建QName
			QName ename = new QName(serviceNs,"add","sx");
			SOAPBodyElement element = soapBody.addBodyElement(ename);
			element.addChildElement("a").setValue("1");
			element.addChildElement("b").setValue("2");
			soapMsg.writeTo(System.out);
			System.out.println("\n");
			//传输并接收响应消息
			SOAPMessage responseMsg = dispatch.invoke(soapMsg);
			responseMsg.writeTo(System.out);
			System.out.println("\n");
			//将返回的消息转换成Document对象
			Document doc = responseMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
			String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
			System.out.println("result:"+str);
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (SOAPException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Test
	public void test04(){
		try {
			//创建服务
			URL url = new URL(webUrl);
			QName qname = new QName(serviceNs, serviceName);
			Service service = Service.create(url, qname);
			//创建Dispatch(负载的方式[字符串])
			Dispatch<Source> dispatch = service.createDispatch(new QName(serviceNs,"MixServiceImplPort"), Source.class, Service.Mode.PAYLOAD);
			//编排对象->xml
			User user = new User(1001,"aaa","111");
			StringWriter sw = new StringWriter();
			JAXBContext jaxbCtx = JAXBContext.newInstance(User.class);
			Marshaller mar = jaxbCtx.createMarshaller();
			//去掉xml头信息<?xml version="1.0" encoding="utf-8"?>
			mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
			mar.marshal(user, sw);
			System.out.println("user-xml:"+sw);
			//创建payload
			String payload="<sx:addUser xmlns:sx=\""+serviceNs+"\">"+sw.toString()+"</sx:addUser>";
			System.out.println("payload:"+payload);
			StreamSource payloadSource = new StreamSource(new StringReader(payload));
			//返回的是StAXSource
			Source responseSource =  dispatch.invoke(payloadSource);
			//将返回的Source对象转换成DOM
			DOMResult domResult =  new DOMResult();
			Transformer transformer = TransformerFactory.newInstance().newTransformer();
			transformer.transform(responseSource, domResult);
			Document doc = (Document) domResult.getNode();
			//读取返回信息并反编排成对象
			XPath xpath = XPathFactory.newInstance().newXPath();
			NodeList users = (NodeList) xpath.evaluate("//user", doc, XPathConstants.NODESET);
			User tuser = (User) jaxbCtx.createUnmarshaller().unmarshal(users.item(0));
			System.out.println(tuser);
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}   catch (JAXBException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
	}
	@Test
	public void test05(){
		try {
			//创建服务
			URL url = new URL(webUrl);
			QName qname = new QName(serviceNs, serviceName);
			Service service = Service.create(url, qname);
			//创建Dispatch(消息方式)
			Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(serviceNs,"MixServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
			//创建SOAPMessage
			SOAPMessage soapMsg = MessageFactory.newInstance().createMessage();
			SOAPEnvelope soapEnvelope = soapMsg.getSOAPPart().getEnvelope();
			SOAPBody soapBody = soapEnvelope.getBody();
			//创建QName
			QName ename = new QName(serviceNs,"getUsers","sx");
			soapBody.addBodyElement(ename);
			System.out.println("\n");
			//传输并接收响应消息
			SOAPMessage responseMsg = dispatch.invoke(soapMsg);
			responseMsg.writeTo(System.out);
			System.out.println("\n");
			//将返回的消息转换成Document对象
			Document doc = responseMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
			NodeList users = doc.getElementsByTagName("user");
			JAXBContext jaxbCtx = JAXBContext.newInstance(User.class);
			for(int i=0;i<users.getLength();i++){
				User tuser = (User) jaxbCtx.createUnmarshaller().unmarshal(users.item(i));
				System.out.println(tuser);
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (SOAPException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}
	@Test
	public void test06(){
		try {
			//创建服务
			URL url = new URL(webUrl);
			QName qname = new QName(serviceNs, serviceName);
			Service service = Service.create(url, qname);
			
			//创建Dispatch(消息方式)
			Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(serviceNs,"MixServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE);
			
			//创建SOAPMessage
			SOAPMessage soapMsg = MessageFactory.newInstance().createMessage();
			SOAPEnvelope soapEnvelope = soapMsg.getSOAPPart().getEnvelope();
			SOAPBody soapBody = soapEnvelope.getBody();
			
			//创建QName
			QName ename = new QName(serviceNs,"login","sx");
			SOAPBodyElement element = soapBody.addBodyElement(ename);
			element.addChildElement("username").setValue("xxx");
			element.addChildElement("password").setValue("xxx123");
			
			//传输并接收响应消息
			SOAPMessage responseMsg = dispatch.invoke(soapMsg);
			responseMsg.writeTo(System.out);
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} 
	}
	
}
